package me.keiwu.api.filter;

import com.alibaba.fastjson.JSON;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import me.keiwu.api.rpc.UserRpc;
import me.keiwu.pub.data.GlobalConst;
import me.keiwu.pub.data.Response;
import me.keiwu.pub.data.service.UserInfoBean;
import me.keiwu.pub.util.TokenUtil;
import me.keiwu.pub.util.CacheUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.AntPathMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by kei on 07/11/2017.
 */
public class AccessFilter extends ZuulFilter {

    private static final Logger logger = LoggerFactory.getLogger(AccessFilter.class);

    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private TokenUtil tokenUtil;
    @Autowired
    private UserRpc userRpc;


    private static AntPathMatcher MATCHER = new AntPathMatcher();



    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        HttpServletResponse response = ctx.getResponse();

        String uri = request.getRequestURI();
        // 登录和后台不拦截
        boolean noNeedToken = MATCHER.match("/user/login/**", uri)
                || MATCHER.match("/admin/**", uri)
                || MATCHER.match("/*/pub/**", uri);
        if (noNeedToken) return true;

        // 小程序权限管理模块
        String token = request.getParameter("access_token");
        if (StringUtils.isBlank(token)) {
            logger.info("access_token is blank!");
            token = request.getHeader("Authorization");
        }
        logger.info("request token={}", token);
        Long userId = TokenUtil.parseUserId(token);
        if (userId == null || !tokenUtil.checkAccessToken(token)) {
            logger.error("wrong access_token！ userId={}, token={}", userId, token);
            try {
                response.getWriter().write(Response.fail(-1, "token expired!").toString());
            } catch (IOException e) {
                // ignore
            }
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.setStatus(200);
            ctx.setSendZuulResponse(false);
            return false;
        }

        logger.info("check token success, token={}, userId={}", token, userId);

        String userInfo = userRpc.userInfoCache(userId);
        UserInfoBean userInfoBean = JSON.parseObject(userInfo, UserInfoBean.class);
        if (userInfo != null) {
            // 刷新token
            tokenUtil.updateAccessToken(userId, token);
            ctx.addZuulRequestHeader(GlobalConst.REQUEST_HEADER_USER_ID, "" + userId);
            ctx.addZuulRequestHeader(GlobalConst.REQUEST_HEADER_NICK_NAME, userInfoBean.getNickName());
            return true;
        }
        return false;
    }
}
